export function generateRandomNumbers(form: {
    count: number;
    targetMean: number;
    targetStdDev: number;
    maxValue?: number;
    decimalPlaces?: number;
}) {
    let { count, targetMean, targetStdDev, maxValue = Infinity, decimalPlaces = 0 } = form;

    const eps = 10 ** -Math.max(decimalPlaces + 2, 8);   // 计算精度
    const unit = 10 ** -decimalPlaces;                    // 最小调整刻度

    /* ---------- 工具函数 ---------- */
    const round = (n: number) => Math.round(n / unit) * unit;

    const normalRandom = (mean: number, sd: number) => {
        let u = 0,
            v = 0;
        while (u === 0) u = Math.random();
        while (v === 0) v = Math.random();
        return mean + sd * Math.sqrt(-2 * Math.log(u)) * Math.cos(2 * Math.PI * v);
    };

    const mean = (arr: number[]) => arr.reduce((a, b) => a + b, 0) / arr.length;
    const sd   = (arr: number[]) => {
        const m = mean(arr);
        return Math.sqrt(arr.reduce((s, v) => s + (v - m) ** 2, 0) / (arr.length - 1));
    };

    /* ---------- 1. 先生成初始样本 ---------- */
    let nums: number[] = [];
    for (let i = 0; i < count; ++i) {
        let v: number;
        do {
            v = round(normalRandom(targetMean, targetStdDev));
        } while (v < 0 || v > maxValue);
        nums.push(v);
    }

    /* ---------- 2. 把均值调到 ≥ targetMean ---------- */
    while (mean(nums) < targetMean - eps) {
        // 找最小值加 1 个 unit，对均值提升贡献最大，对标准差影响最小
        let minIdx = 0;
        for (let i = 1; i < nums.length; ++i) if (nums[i] < nums[minIdx]) minIdx = i;

        const next = round(nums[minIdx] + unit);
        if (next > maxValue) break; // 不能再加
        nums[minIdx] = next;
    }

    /* ---------- 3. 在均值已达标的前提下，把标准差压到 < targetStdDev ---------- */
    while (true) {
        const currentSd = sd(nums);
        if (currentSd < targetStdDev - eps) break; // 已满足

        // 找出对降低标准差最有效的那个数：离均值最远的数向均值靠拢
        const m = mean(nums);
        let bestIdx = 0,
            bestGain = 0;

        for (let i = 0; i < nums.length; ++i) {
            const dir = nums[i] > m ? -1 : 1;                // 向均值方向
            const cand = round(nums[i] + dir * unit);
            if (cand < 0 || cand > maxValue) continue;

            // 快速估算方差下降量 ≈ 2 * (x_i - m) * dir * unit
            const gain = 2 * (nums[i] - m) * dir * unit;
            if (gain > bestGain) {
                bestGain = gain;
                bestIdx = i;
            }
        }

        if (bestGain === 0) break; // 已无法继续降低
        const dir = nums[bestIdx] > m ? -1 : 1;
        nums[bestIdx] = round(nums[bestIdx] + dir * unit);
    }

    /* ---------- 4. 随机打乱 ---------- */
    for (let i = nums.length - 1; i > 0; --i) {
        const j = (Math.random() * (i + 1)) | 0;
        [nums[i], nums[j]] = [nums[j], nums[i]];
    }

    return nums.map((n) => n.toFixed(decimalPlaces));
}